using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Actions;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Framework;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;
using System.Text.RegularExpressions;
using DotNetNuke.Services.Tokens;
using SE.HTMLRepeater.Components;

namespace SE.HTMLRepeater
{
    public partial class View : PortalModuleBase, IActionable
    {
        public bool IsModuleConfigured { get; set; }
        public int PageSize { get; set;}
        public int PageNumber { get; set; }
        public bool Paging { get; set; }
        public bool FlowLayout { get; set; }
        public int Pages { get; set; }
        
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {

                ltConfigMessage.Text = "<!--Software's Edge HTR Module-->";
                if (Settings["pageSize"] != null && !string.IsNullOrEmpty(Settings["pageSize"].ToString()))
                {
                    PageSize = Convert.ToInt16(Settings["pageSize"]);
                    Paging = (PageSize > 0);
                }

                if (Settings["flowLayout"] != null && !string.IsNullOrEmpty(Settings["flowLayout"].ToString()))
                {
                    FlowLayout = Convert.ToBoolean(Settings["flowLayout"]);
                    

                }

                
                if (!IsPostBack)
                {
                    PageNumber = 1;//Convert.ToInt16(hPageNumber.Value);
                    bindItems();
                }else
                {
                    PageNumber = Convert.ToInt16(hPageNumber.Value);
                }


                //tell user that they need to configure the module.
                if (Settings["template"] != null && !string.IsNullOrEmpty(Settings["template"].ToString()))
                {
                    IsModuleConfigured = true;
                }
                else
                {
                    ltConfigMessage.Text = Localization.GetString("defaultMessage", this.LocalResourceFile); 
                }

                
                

            }
            catch (Exception ex)
            {
                Exceptions.ProcessModuleLoadException(this, ex);
            }
        }
        public void bindItems()
        {
            
            List<HTMLRepeaterInfo> items;
            HTMLRepeaterController controller = new HTMLRepeaterController();
            if (!Paging)
            {
                items = controller.GetHTMLRepeaters(this.ModuleId);

            }
            else
            {

                items = controller.GetHTMLRepeatersPaged(this.ModuleId, PageNumber, PageSize);
            }

			if (items.Count != 0)
			{
				IsModuleConfigured = IsEditable;
				//bind the data
				lstContent.DataSource = items;
				lstContent.DataBind();

				if (Paging)
				{
					CreatePagers(controller);
				}
			}
			else
			{
				ltConfigMessage.Text = "This module has no elements to display. Click on the add content link to add data elements.";
			}


        	hPageNumber.Value = PageNumber.ToString();

        }

        public void CreatePagers(HTMLRepeaterController controller)
        {
            int count = controller.GetHTMLRepeatersCount(ModuleId);
            
            Pages = count/PageSize;
            if (Pages*PageSize != count)
            {
                ++Pages; //add one for partial last page.
            }

            List<int> ThePages = new List<int>();
            
            for (int i = 1; i < Pages+1; i++)
            {
               ThePages.Add(i);
            }

            rptrTPager.DataSource = ThePages;
            rptrBPager.DataSource = ThePages;
            rptrTPager.DataBind();
            rptrBPager.DataBind();
            
        }


        #region IActionable Members

        public DotNetNuke.Entities.Modules.Actions.ModuleActionCollection ModuleActions
        {
            get 
            {
                //create a new action to add an item, this will be added to the controls
                //dropdown menu
                
                    ModuleActionCollection actions = new ModuleActionCollection();
                    if (Settings["template"] != null && !string.IsNullOrEmpty(Settings["template"].ToString()))
                    {
                        actions.Add(GetNextActionID(), Localization.GetString(ModuleActionType.AddContent, this.LocalResourceFile),
                                    ModuleActionType.AddContent, "", "", EditUrl(), false, DotNetNuke.Security.SecurityAccessLevel.Edit,
                                    true, false);
                    }

                    string TemplateEditMenuText = Localization.GetString("EditModuleTemplate", this.LocalResourceFile);
                    actions.Add(GetNextActionID(), TemplateEditMenuText, TemplateEditMenuText, "", "", EditUrl("EditModuleTemplate") , false, DotNetNuke.Security.SecurityAccessLevel.Edit,true,false);

                    string ManageExistingTemplatesMenuText = Localization.GetString("ManageExistingTemplates", this.LocalResourceFile);
                    actions.Add(GetNextActionID(), ManageExistingTemplatesMenuText, TemplateEditMenuText, "", "", EditUrl("ManageExistingTemplates"), false, DotNetNuke.Security.SecurityAccessLevel.Edit, true, false);

                    return actions;
                
                
            }
        }

        #endregion


        /// <summary>
        /// Handles the items being bound to the datalist control. In this method we merge the data with the
        /// template defined for this control to produce the result to display to the user
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lstContent_ItemDataBound(object sender, System.Web.UI.WebControls.DataListItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {

                Literal content = (Literal) e.Item.FindControl("theHtml");
                HtmlGenericControl FlowControllerDiv = (HtmlGenericControl)e.Item.FindControl("dataItem");

                if(FlowLayout)
                {
                    FlowControllerDiv.Attributes["class"] = "SEHTRdataItemFlow";
                }
                else
                {
                    FlowControllerDiv.Attributes["class"] = "SEHTRdataItem";
                }



                string templateContentValue = string.Empty;
                string readyContent = "";

                if (Settings["template"] != null)
                {
                    //apply the content to the template
                    ArrayList propInfos = CBO.GetPropertyInfo(typeof (HTMLRepeaterInfo));
                    templateContentValue = Settings["template"].ToString();


                    foreach (PropertyInfo propInfo in propInfos)
                    {
                        object propertyValue = DataBinder.Eval(e.Item.DataItem, propInfo.Name);
                        if (propertyValue != null)
                        {
                            templateContentValue = templateContentValue.Replace("[" + propInfo.Name.ToUpper() + "]",
                                                                                Server.HtmlDecode(propertyValue.ToString()));
                        }
                    }
                    //Token replacement the DNN way.
                    PortalSettings objPortalSettings = PortalController.GetCurrentPortalSettings();
                    TokenReplace tr = new TokenReplace();
                    tr.AccessingUser = UserController.GetCurrentUserInfo();
                    tr.DebugMessages = !(objPortalSettings.UserMode == PortalSettings.Mode.View);
                    tr.ModuleId = ModuleId;
                    templateContentValue = tr.ReplaceEnvironmentTokens(templateContentValue);
                }




                string variables = DataBinder.Eval(e.Item.DataItem, "Content").ToString();
                List<DisplayVar> Dvs = Util.DecompressVariables(variables);

                foreach (DisplayVar dv in Dvs)
                {
                    templateContentValue = templateContentValue.Replace("!" + dv.VarName + "!", dv.VarValue);
                }

                readyContent = Server.HtmlDecode(templateContentValue);

                content.Mode = LiteralMode.Transform;
                content.Text = readyContent;
            }
        }

        private string GetPropByName(object o,string Name)
        {
            PropertyInfo pi = o.GetType().GetProperty(Name);
            object x = pi.GetValue(o, null);
            if (x == null)
            { return ""; }
            else {return x.ToString();}
        }

        protected void rptrPager_ItemDataBound(object sender,System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            LinkButton linkButton = (LinkButton)e.Item.FindControl("Pager");

            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                
                linkButton.Text = e.Item.DataItem.ToString();
                linkButton.CommandName = "page";
                linkButton.ToolTip = "Click to go to page: " + e.Item.DataItem.ToString();
                linkButton.CommandArgument = e.Item.DataItem.ToString();
                linkButton.CssClass = "SEHTRpager Breadcrumb";
                if(PageNumber == Convert.ToInt16(e.Item.DataItem))
                {
                    linkButton.CssClass = "SEHTRCurentPage Breadcrumb";
                    linkButton.ToolTip = "Current Page";
                }
            }
            else if (e.Item.ItemType == ListItemType.Header )
            {
                
                if (PageNumber != 1)
                {
                    linkButton.ToolTip = "Pervious Page";
                }
                else
                {
                    linkButton.Visible = false;
                }
            }
            else if(e.Item.ItemType == ListItemType.Footer)
            {
                
                if (PageNumber != Pages)
                {
                    linkButton.ToolTip = "Next Page";
                }
                else
                {
                    linkButton.Visible = false;
                }
            }


        }

        protected void rptrPager_ItemCommand(Object source,RepeaterCommandEventArgs e)
        {
            if(e.CommandName == "page")
            {
                this.PageNumber = Convert.ToInt16(e.CommandArgument);
            }
            if(e.CommandName == "pageNext")
            {
                PageNumber++;
            }
            if (e.CommandName == "pagePrev")
            {
                PageNumber--;
            }

            bindItems();
        }


        public static Match[] FindSubstrings(string source,string matchPattern, bool findAllUnique)
        {
            SortedList uniqueMatches = new SortedList();
            Match[] retArray = null;
            Regex RE = new Regex(matchPattern, RegexOptions.Multiline);
            MatchCollection theMatches = RE.Matches(source);
            if (findAllUnique)
            {
                for (int counter = 0; counter < theMatches.Count; counter++)
                {
                    if (!uniqueMatches.ContainsKey(theMatches[counter].Value))
                    {
                        uniqueMatches.Add(theMatches[counter].Value,
                        theMatches[counter]);
                    }
                }
                retArray = new Match[uniqueMatches.Count];
                uniqueMatches.Values.CopyTo(retArray, 0);
            }
            else
            {
                retArray = new Match[theMatches.Count];
                theMatches.CopyTo(retArray, 0);
            }
            return (retArray);
        }
    }
}